<template>
  <div class="bg">
    <div class="contain">
      <el-form
        ref="loginForm"
        :model="loginForm"
        :rules="rules"
        class="login_container"
        label-position="left"
        label-width="0px"
        v-loading="loading"
        @keyup.enter.native="comparePicCode('loginForm')"
      >
        <h3 class="login_title">系统登录</h3>
        <el-form-item prop="username">
          <el-input
            type="text"
            v-model="loginForm.username"
            auto-complete="off"
            placeholder="账号"
          ></el-input>
        </el-form-item>
        <el-form-item prop="password">
          <el-input
            type="password"
            v-model="loginForm.password"
            auto-complete="off"
            placeholder="密码"
          ></el-input>
        </el-form-item>
        <el-form-item prop="code" style="position: relative; top: -10px">
          <el-input
            type="text"
            v-model="loginForm.code"
            auto-complete="off"
            placeholder="验证码"
            style="width: 227px"
          ></el-input>
          <img :src="imgSrc" @click="getCode" class="img_code" />
        </el-form-item>

        <el-checkbox
          class="login_remember"
          v-model="checked"
          label-position="left"
          style="
            margin-bottom: 0px;
            position: relative;
            top: -15px;
            left: -123px;
          "
        >
          记住密码
        </el-checkbox>

        <el-form-item style="width: 100%; text-align: center">
          <el-button
            type="primary"
            @click.native.prevent="comparePicCode('loginForm')"
          >
            立即登录
          </el-button>
          <el-button
            type="primary"
            @click="faceScanOpen"
            style="margin-left: 20px"
          >
            刷脸登录
          </el-button>
        </el-form-item>
      </el-form>
    </div>
    <div class="faceScan" v-if="faceScan">
      <div class="mask"></div>
      <div class="pop">
        <span style="font-family: 'Britannic Bold', 'Britannic'; color: #3bc5bb"
          >CSI员工</span
        >
        <span style="color: #1d4474"></span>
        <span style="color: #ff9a4c">之家</span>
        <div>请将面部置于摄像头前</div>
        <div id="media">
          <video
            id="video"
            ref="video"
            width="100%"
            height="300"
            autoplay
          ></video>
        </div>
        <el-button
          type="primary"
          @click="photo"
          style="position: absolute; bottom: 20px; left: 65px"
        >
          登录
        </el-button>
        <el-button
          type="primary"
          @click="faceScanClose"
          style="position: absolute; bottom: 20px; right: 65px"
        >
          取消
        </el-button>
      </div>
    </div>
    <canvas
      ref="canvas"
      width="300"
      height="200"
      style="display: none"
    ></canvas>
  </div>
</template>

<script>
export default {
  name: "loginForm",
  data() {
    return {
      rules: {
        username: [
          { required: true, message: "请输入用户名", trigger: "blur" },
        ],
        password: [{ required: true, message: "请输入密码", trigger: "blur" }],
        code: [{ required: true, message: "请输入验证码", trigger: "blur" }],
      },
      loginForm: {
        username: "",
        password: "",
        code: "",
      },
      faceImg: { image: "" },
      checked: false,
      faceScan: false,
      loading: false,
      imgSrc: "", //验证码
    };
  },
  mounted() {
    this.getCode();
    this.getCookie();
  },
  methods: {
    getCode() {
      window.localStorage.removeItem("loginVerifyCodeKey");
      let loginVerifyCodeKey = Date.now() + Math.ceil(Math.random() * 100);
      //使用 localStorage 创建一个本地存储的 name/value 对
      window.localStorage.setItem("loginVerifyCodeKey", loginVerifyCodeKey);
      this.imgSrc =
        window.location.origin +
        "/api" +
        "/verifyCode/getCode/" +
        loginVerifyCodeKey; // 给图片地址配一个无用的随机数
    },
    // 验证验证码
    comparePicCode(formName) {
      this.$refs[formName].validate((valid) => {
        if (valid) {
          let url =
            "/verifyCode/comparePicCode/" +
            this.loginForm.code +
            "/" +
            window.localStorage.getItem("loginVerifyCodeKey");
          this.$request.get(url).then((res) => {
            if (res.data.obj === "正确") {
              this.submitClick();
            } else if (res.data.obj === "错误") {
              this.getCode();
              this.loginForm.code = "";
              this.$message.error("验证码错误");
            } else {
              this.getCode();
              this.loginForm.code = "";
              this.$message.error("验证码已过期");
            }
          });
        } else {
          this.$message.error("请完成输入后再提交");
        }
      });
    },
    // 验证账号密码
    submitClick: function () {
      let that = this;
      this.$request
        .postForm("/securityUser/login", this.loginForm)
        .then((res) => {
          if (res.data.obj !== "账号或密码错误") {
            this.$message.success("登录成功");
            //将用户权限放入session存储中
            window.sessionStorage.setItem(
              "authority",
              res.data.obj.roleList[0].authority
            );
            window.sessionStorage.setItem("username", res.data.obj.username);
            //将token令牌放入会话存储中
            window.sessionStorage.setItem("token", res.data.obj.token);
            //吧员工id存储
            window.sessionStorage.setItem(
              "employeeId",
              res.data.obj.employeeId
            );
            if (this.checked === true) {
              that.setCookie(
                that.loginForm.username,
                that.loginForm.password,
                7
              );
            }
            this.$router.push("/about"); //跳转到关于页
          } else {
            this.getCode();
            this.loginForm.username = "";
            this.loginForm.password = "";
            this.loginForm.code = "";
            this.$message.error(res.data.obj);
          }
        });
    },
    //设置cookie
    setCookie(c_name, c_pwd, c_days) {
      let date = new Date(); //获取时间
      date.setTime(date.getTime() + 24 * 60 * 60 * 1000 * c_days); //保存的天数
      //字符串拼接cookie
      window.document.cookie =
        "userName" + "=" + c_name + ";path=/;expires=" + date.toGMTString();
      window.document.cookie =
        "userPwd" + "=" + c_pwd + ";path=/;expires=" + date.toGMTString();
    },
    //读取cookie
    getCookie: function () {
      if (document.cookie.length > 0) {
        let arr = document.cookie.split("; "); //这里显示的格式需要切割一下自己可输出看下
        // console.log('cookie', arr)
        for (let i = 0; i < arr.length; i++) {
          let arr2 = arr[i].split("="); //再次切割
          //判断查找相对应的值
          if (arr2[0] == "userName") {
            this.loginForm.username = arr2[1]; //保存到保存数据的地方
          } else if (arr2[0] == "userPwd") {
            this.loginForm.password = arr2[1];
          }
        }
      }
    },
    //清除cookie
    clearCookie: function () {
      this.setCookie("", "", -1); //修改2值都为空，天数为负1天就好了
    },

    //打开摄像头
    faceScanOpen() {
      this.faceScan = true;
      // H5调用电脑摄像头API
      navigator.mediaDevices
        .getUserMedia({
          audio: false, //开启音频
          video: true, //开启视频
        })
        .then((success) => {
          var videoTracks = success.getVideoTracks();
          // console.log(success);
          // console.log(videoTracks);
          // 摄像头开启成功
          this.$refs["video"].srcObject = success;
          this.isCameraFlag = false;
          // 实时拍照效果
          this.$refs["video"].play();
        })
        .catch(() => {
          console.error("摄像头开启失败，请检查摄像头是否可用！");
          this.isCameraFlag = true;
        });
    },
    photo() {
      // 把当前视频帧内容渲染到canvas上
      let ctx = this.$refs["canvas"].getContext("2d");
      ctx.drawImage(this.$refs["video"], 0, 0, 320, 240);
      //void ctx.drawImage(image, dx, dy, dWidth, dHeight);
      /* dx  image的左上角在目标canvas上 X 轴坐标。dWidth可选image在目标canvas上绘制的宽度。 允许对绘制的image进行缩放。 如果不说明， 在绘制时image宽度不会缩放。 */
      /**------------后面是下载功能----------*/
      // 转base64格式、图片格式转换、图片质量压缩---支持两种格式image/jpeg+image/png
      let imgBase64 = this.$refs["canvas"].toDataURL("image/jpeg", 0.7);
      // 由字节转换为KB 判断大小
      let str = imgBase64.replace("data:image/jpeg;base64,", "");
      console.log(str);

      //测试用
      // this.faceImg.image = xxx;
      //正式使用时
      this.faceImg.image = str;
      let strLength = str.length;
      let fileLength = parseInt(strLength - (strLength / 8) * 2); // 图片尺寸  用于判断  尺寸过大会导致请求头过长
      let size = (fileLength / 1024).toFixed(2);
      console.log(size); // 上传拍照信息  调用接口上传图片 .........
      // 保存到本地;
      // let ADOM = document.createElement("a");
      // ADOM.href = this.headImgSrc;
      // ADOM.download = new Date().getTime() + ".jpeg";
      // ADOM.click();
      // this.$router.push("/about"); //跳转到关于页
      this.faceScanClose(); //关闭摄像头
      this.$request
        .postForm("/securityUser/faceLogin", this.faceImg)
        .then((res) => {
          if (res.data.msg == "success") {
            this.$message.success("登录成功");
            //将用户权限放入session存储中
            window.sessionStorage.setItem(
              "authority",
              res.data.obj.roleList[0].authority
            );
            window.sessionStorage.setItem("username", res.data.obj.username);
            //将token令牌放入会话存储中
            window.sessionStorage.setItem("token", res.data.obj.token);
            //吧员工id存储
            window.sessionStorage.setItem(
              "employeeId",
              res.data.obj.employeeId
            );
            this.$router.push("/about"); //跳转到关于页
          } else {
            this.getCode();
            this.$message.error(res.data.obj);
          }
        });
    },
    //关闭摄像头
    faceScanClose() {
      this.faceScan = false;
      if (!this.$refs["video"].srcObject) return;
      let stream = this.$refs["video"].srcObject;
      let tracks = stream.getTracks();
      tracks.forEach((track) => {
        track.stop();
      });
      this.$refs["video"].srcObject = null;
      this.isCameraFlag = true;
    },
  },
};
</script>

<style scoped>
.login_container {
  border-radius: 15px;
  background-clip: padding-box;
  margin: 180px auto;
  width: 400px;
  padding: 35px 35px 15px 35px;
  background: #fff;
  border: 1px solid #eaeaea;
  box-shadow: 0 0 25px #cac6c6;
}

.login_title {
  margin: 0px auto 40px auto;
  text-align: center;
  color: #505458;
}

.login_remember {
  margin: 0px 0px 35px 0px;
  text-align: left;
}

.img_code {
  position: relative;
  top: 12px;
}
.remPWD {
  position: absolute;
  font-size: 14px;
}

span {
  display: inline-block;
  font-size: 32px;
  line-height: 10px;
  height: 32px;
}
.bg {
  background: url("../assets/login_bg.jpg") no-repeat center;
  height: 100%;
  width: 100%;
  background-size: cover;
  position: fixed;
  top: 0;
  left: 0;
}
.contain {
  /* 弹性布局水平居中 */
  text-align: center;
  display: flex;
  justify-content: center;
  align-items: center;
  /* body最小高度为100%窗口高度 */
  min-height: 100vh;
}

.wrapper {
  width: 450px;
  background-color: #fff;
  /* 内边距（上下左右） */
  padding: 40px;
  /* 盒子阴影 */
  box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.1);
  border-radius: 8px;
}

.wrapper .input-data {
  /* 相对定位 */
  position: relative;

  width: 100%;
  height: 40px;
  margin-bottom: 25px;
}

.wrapper .input-data input {
  width: 100%;
  height: 100%;
  border: none;
  font-size: 17px;
  border-bottom: 2px solid #c0c0c0;

  margin: 0;
  padding: 0;
  outline: none;
  /* 边框和内边距包含在总宽高内 */
  box-sizing: border-box;
}

.wrapper .input-data input:focus ~ label,
.wrapper .input-data input:valid ~ label {
  /* 输入框获得焦点时,输入值合法时 */
  transform: translateY(-25px);
  font-size: 15px;
  color: #2c6fdb;
}

.wrapper .input-data label {
  /* 绝对定位 */
  position: absolute;
  bottom: 10px;
  left: 0px;
  color: #333;
  pointer-events: none;
  /* 动画过渡显得不生硬 */
  transition: all 0.3s ease;
}

.wrapper .input-data .underline {
  position: absolute;
  bottom: 0px;
  height: 2px;
  width: 100%;
  background-color: #2c6fdb;
  transform: scaleX(0);
  /* 延X轴缩小 */
  transition: all 0.3s ease;
  /* 加过度 */
}

.wrapper .input-data input:focus ~ .underline,
.wrapper .input-data input:valid ~ .underline {
  transform: scaleX(1);
  /* 延X放大 */
}
.LoginUp {
  text-decoration: none;
  color: rgb(64, 158, 255);
  margin-right: -100px;
  margin-left: 10px;
  font-size: 12px;
}
.mask {
  background-color: rgba(0, 0, 0, 0.5);
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  z-index: 1;
}
.pop {
  position: fixed;
  top: 100px;
  left: 50%;
  z-index: 2;
  width: 300px;
  height: 400px;
  overflow: hidden;
  margin: 5% auto 0 -150px;
  padding: 20px;
  box-shadow: 0 -15px 30px #fff;
  border-radius: 20px;
}

#media {
  width: 100%;
  height: 250px;
  margin: 10px auto 0;
  border-radius: 30px;
  overflow: hidden;
  opacity: 0.7px;
}
</style>
